package kz.kstu.aecdemo.desktop.ui.dialog;

import kz.kstu.aec.Authenticator;
import kz.kstu.aec.model.ClientData;
import kz.kstu.aec.model.AuthenticationData;
import kz.kstu.aecdemo.app.delegate.api.AccountDelegate;
import kz.kstu.aecdemo.app.delegate.impl.AccountDelegateImpl;
import kz.kstu.aecdemo.business.entity.security.AbstractAccount;
import kz.kstu.aecdemo.business.util.StringUtil;
import kz.kstu.aecdemo.desktop.util.GUIUtils;
import org.apache.log4j.Logger;

import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.LoginException;
import javax.swing.*;
import java.awt.event.*;
import java.math.BigInteger;

public class LoginDialog extends JDialog {

    public static final Logger LOGGER = Logger.getLogger(LoginDialog.class);

    private static final int WIDTH = 320;
    private static final int HEIGHT = 200;

    private static final String TITLE = "Вход в систему";

    private static final String LOGIN_INCORRECT = "Логин не корректен";
    private static final String INCORRECT_LOGIN_OR_PASSWORD = "Логин и/или пароль указан неверно";
    private static final String LOGIN_NOT_FOUND = "Указанный логин не найден";
    private static final String AUTHENTICATION_SUCCESSFULLY_COMPLIED = "Аутентификация успешно завершена";

    private JPanel contentPane;
    private JButton buttonOK;
    private JButton buttonCancel;
    private JTextField loginField;
    private JPasswordField passwordField;
    private JLabel registerLabel;
    private AbstractAccount account;

    public LoginDialog() {
    }

    public AbstractAccount login() {
        initStaticComponents();
        return account;
    }

    private void initStaticComponents() {
        setContentPane(contentPane);
        setModal(true);
        getRootPane().setDefaultButton(buttonOK);
        setSize(WIDTH, HEIGHT);
        setTitle(TITLE);
        initListeners();
        GUIUtils.centerAndShow(this);
    }

    private void initListeners() {

        buttonOK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onOK();
            }
        });

        buttonCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        });

        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        contentPane.registerKeyboardAction(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        onCancel();
                    }
                }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        registerLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                RegisterDialog registerDialog = new RegisterDialog();
                registerDialog.initStaticComponents();

            }
        });

    }

    private void onOK() {
        String login = loginField.getText();
        if (!validateLogin(login)) {
            JOptionPane.showMessageDialog(this, LOGIN_INCORRECT, TITLE, JOptionPane.ERROR_MESSAGE);
            return;
        }
        AccountDelegate accountDelegate = new AccountDelegateImpl();
        try {
            String password = new String(passwordField.getPassword());
            ClientData clientData = new ClientData(login, password);

            Authenticator authenticator = Authenticator.getInstance();
            BigInteger authenticationNumber = accountDelegate.getAuthenticationNumber(login);
            AuthenticationData authenticationData = authenticator.getAuthenticationData(clientData, authenticationNumber);

            account = accountDelegate.login(authenticationData);
            JOptionPane.showMessageDialog(this, AUTHENTICATION_SUCCESSFULLY_COMPLIED, TITLE, JOptionPane.INFORMATION_MESSAGE);
            dispose();
        } catch (AccountNotFoundException e) {
            JOptionPane.showMessageDialog(this, LOGIN_NOT_FOUND, TITLE, JOptionPane.ERROR_MESSAGE);
        } catch (LoginException e) {
            JOptionPane.showMessageDialog(this, INCORRECT_LOGIN_OR_PASSWORD, TITLE, JOptionPane.ERROR_MESSAGE);
        }
    }

    private void onCancel() {
        dispose();
    }

    //TODO: need to move another place
    private boolean validateLogin(String login) {
        return !StringUtil.isEmptyString(login);
    }
}
